UIPickView

UIPickView的属性:

  • picker的高度是固定的,如果设置大于216,就是216,如果小于216大于180,就是180;如果小于180大于162,就是162。

  • 设置数据源及代理(UIPickerViewDelegate,UIPickerViewDataSource)

  picker.dataSource=self;
  picker.delegate=self;
  • 创建
    UIPickerView*picker=[[UIPickerView alloc]initWithFrame:CGRectMake(0, 50, 180, 300)];
    picker.backgroundColor=[UIColor cyanColor];
    [self.view addSubview:picker];

//    设置显示选中的指示条,默认为NO
    picker.showsSelectionIndicator=YES;

//    设置数据源及代理
    picker.dataSource=self;
    picker.delegate=self;

UIPickView的常用方法:

// 刷新整个数据源
- (void)reloadAllComponents;
// 刷新选中列的数据
- (void)reloadComponent:(NSInteger)component;


// (用动画的效果)将指定的行滚动到中心
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated;


// 返回选定的行
- (NSInteger)selectedRowInComponent:(NSInteger)component;


// 加载自定义pickView的行视图 ****
- (nullable UIView *)viewForRow:(NSInteger)row forComponent:(NSInteger)component;

UIPickView的数据源协议:

  • 必须实现的协议方法:
// PickerView有多少列
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;


// PickerView的每一列有多少行
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;

UIPickView的代理协议:

//返回picker 有多少个区
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 3;
}


//返回picker 每个区有多少行
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    return  5;
}


// 如果同时实现返回字符串和view的方法,返回UIView的优先级比较高
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view __TVOS_PROHIBITED
{
// 返回自定义view
    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];

    v.backgroundColor = [UIColor redColor];

    return v;

}


// NSAttributedString富文本属性: 可以描述文字大小和颜色(此方法不常用)
- (nullable NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component;


// 返回pickerView的行标题
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return @"xxxx";
}


// 选中第component第row的时候调用
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
}

例子

例一(自定义pickView中的view)

1、ViewController.m

#import "ViewController.h"
#import "FlageView.h"
#import "flag.h"


@interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>

@property (nonatomic,strong)UIPickerView * pickV;
@property (nonatomic,strong)NSMutableArray * flags;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.



    _pickV = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 100,[UIScreen mainScreen].bounds.size.width, 250)];
    //_pickV.backgroundColor = [UIColor redColor];
    [self.view addSubview:_pickV];
    _pickV.delegate = self;
    _pickV.dataSource = self;

}

// 懒加载
-(NSMutableArray *)flags
{
    if (_flags == nil) {
        _flags = [NSMutableArray array];
        NSString * filePath = [[NSBundle mainBundle]pathForResource:@"flags.plist" ofType:nil];

        // 获取plist数据
        NSMutableArray * array = [NSMutableArray arrayWithContentsOfFile:filePath];

        // 字典数据转换成模型数据
        /*
        (实质就是将字典dic中的数据按照key赋值给flag数据模型)
         如:
         flag * flags = [[flag alloc]init];
         flags.name = dic[@"name"];
         flags.icon = dic[@"icon"];
         */
        for (NSDictionary * dic in array) {
            flag * flags = [flag flagWithDic:dic];
             [_flags addObject:flags];
        }
    }
    NSLog(@"%@",_flags);
    return _flags;
}



- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return self.flags.count;
}


- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
    return 60;
}


- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    FlageView * flagV = [[FlageView alloc]init];

    // 取模型数据
    flag * flg = _flags[row];

    flagV.flag =flg;

    return flagV;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

2、设置view的数据模型

#import <Foundation/Foundation.h>

@interface flag : NSObject

@property (nonatomic,copy)NSString * name;
@property (nonatomic,copy)NSString * icon;

+ (instancetype)flagWithDic:(NSDictionary *)dic;

@end
#import "flag.h"

@implementation flag

// 将字典中的数据转换成模型数据
+ (instancetype)flagWithDic:(NSDictionary *)dic
{
    flag * flag = [[self alloc]init];
    [flag setValuesForKeysWithDictionary:dic];

    return flag;
}
@end

3、自定义view

#import <UIKit/UIKit.h>
#import "flag.h"
@interface FlageView : UIView

@property (nonatomic,strong)UILabel * label;
@property (nonatomic,strong)UIImageView * imageView;

@property (nonatomic,strong)flag * flag;

- (instancetype)initWithFrame:(CGRect)frame;

- (void)setFlag:(flag *)flag;

@end
#import "FlageView.h"
#define  WIDTH  [UIScreen mainScreen].bounds.size.width
@implementation FlageView


- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.frame =CGRectMake(0, 0,WIDTH, 70);
        self.label = [[UILabel alloc]initWithFrame:CGRectMake(0, 5, 100, 60)];
        [self addSubview:self.label];

        self.imageView = [[UIImageView alloc]initWithFrame:CGRectMake(WIDTH-100, 5, 100, 60)];
        [self addSubview:self.imageView];
    }
    return self;
}


- (void)setFlag:(flag *)flag
{
    self.label.text = flag.name;
    self.imageView.image = [UIImage imageNamed:flag.icon];
}

@end
例二(生日选择器)
#import "ViewController.h"

@interface ViewController ()<UITextFieldDelegate>

@property (nonatomic,strong)UITextField * birthdayTF;
@property (nonatomic, weak) UIDatePicker *datePicker;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _birthdayTF = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 100, 44)];

   // 设置文本框的代码
    _birthdayTF.delegate = self;

    [self.view addSubview:_birthdayTF];

    // 自定义生日键盘
    [self setUpBirthdayKeyboard];
}



#pragma mark -自定义生日键盘
- (void)setUpBirthdayKeyboard
{
    // 创建UIDatePicker
    // 注意:UIDatePicker有默认的尺寸,可以不用设置frame
    UIDatePicker *picker = [[UIDatePicker alloc] init];

    _datePicker = picker;

    // 设置地区 zh:中国
    picker.locale = [NSLocale localeWithLocaleIdentifier:@"zh"];

    // 设置日期的模式
    picker.datePickerMode = UIDatePickerModeDate;

    // 监听UIDatePicker的滚动
    [picker addTarget:self action:@selector(dateChange:) forControlEvents:UIControlEventValueChanged];


    _birthdayTF.inputView = picker;
}

// 当UIDatePicker滚动的时候调用
// 给生日文本框赋值
- (void)dateChange:(UIDatePicker *)datePicker
{
    NSLog(@"%@",datePicker.date);
    // 日期转换字符串

    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

    fmt.dateFormat = @"yyyy-MM-dd";

    NSString *dateStr = [fmt stringFromDate:datePicker.date];

    _birthdayTF.text = dateStr;
}



#pragma mark - UITextFieldDelegate

// 是否允许用户输入文字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    return NO;
}

// 文本框开始编辑的时候调用
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
 [self dateChange:_datePicker];
}
例三(城市选择器)
#import "ViewController.h"

@interface ViewController ()<UITextFieldDelegate,UIPickerViewDataSource,UIPickerViewDelegate>

@property (nonatomic,strong)UITextField * cityTF;
@property (nonatomic, weak) UIDatePicker *datePicker;
@property (nonatomic, strong) NSMutableArray *provinces;
@property (nonatomic, assign) NSInteger proIndex;// 记录下第0列选中的省份

@end

@implementation ViewController

// 懒加载省会
- (NSMutableArray *)provinces
{
    if (_provinces == nil) {
        // 装所有的省会
        _provinces = [NSMutableArray array];

        // 加载plist文件
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"provinces.plist" ofType:nil];
        NSArray *arr = [NSArray arrayWithContentsOfFile:filePath];

        for (NSDictionary *dict in arr) {
            // 字典转模型
            XMGProvince *p = [XMGProvince provinceWithDict:dict];

            [_provinces addObject:p];
        }
    }
    return _provinces;
}



- (void)viewDidLoad {
    [super viewDidLoad];

    _cityTF = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 100, 44)];

   // 设置文本框的代码
    _cityTF.delegate = self;


    [self.view addSubview:_cityTF];

    // 自定义生日键盘
    [self setUpCityKeyboard];
}


#pragma mark - UITextFieldDelegate

// 是否允许用户输入文字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    return NO;
}

// 文本框开始编辑的时候调用
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
  [self pickerView:_pickerView didSelectRow:0 inComponent:0];
}



#pragma mark - 自定义城市键盘
- (void)setUpCityKeyboard
{
    UIPickerView *pickerView = [[UIPickerView alloc] init];

    _pickerView = pickerView;

    pickerView.dataSource = self;
    pickerView.delegate = self;

    _cityField.inputView = pickerView;
}


#pragma mark -UIPickerView
#pragma mark UIPickerView的数据源
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 2;
}


// pickerView的第0列描述省会,有多少个省
// pickerView的第1列描述选中的省会,有多少个城市
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if (component == 0) { // 描述省会

        return self.provinces.count;


    }else{ // 描述选中的省会的城市



        // 获取省会
        XMGProvince *p = self.provinces[_proIndex];

        return p.cities.count;

    }
}
#pragma mark -UIPickerView的代理
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == 0) { // 描述省会

        // 获取省会
        XMGProvince *p = self.provinces[row];
        return p.name;

    }else{ // 描述选中的省会的城市

        // 记录当前选中的省会
        _proIndex = [pickerView selectedRowInComponent:0];

        // 获取选中省会
        XMGProvince *p = self.provinces[_proIndex];

#warning 如果不用_proIndex记录第0列选择的省,会导致在下面出现数组越界。
        return p.cities[row];
    }
}

// 全局断点就是帮我们定位到出bug的那一行。

// 滚动UIPickerView就会调用
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    if (component == 0)
    {
    // 滚动省会,刷新城市(1列)
        [pickerView reloadComponent:1];
    }

    // 给城市文本框赋值

    // 获取选中省会
    XMGProvince *p = self.provinces[_proIndex];

    // 获取选中的城市
    NSInteger cityIndex = [pickerView selectedRowInComponent:1];

    NSString *cityName = p.cities[cityIndex];

    _cityTF.text = [NSString stringWithFormat:@"%@ %@",p.name,cityName];
}

results matching ""

    No results matching ""